import numpy as np
import os
import pandas as pd


def read_market_data(file_path):#中长期电量  #日前电量
    param_names = [
         "中长期价格",
         "基数价格", 
         "参考价格",
    ]
    
    # 读取Excel文件
    df = pd.read_excel(file_path, header=None)
    
    if df.shape[0] != len(param_names):
        raise ValueError(f"需要{len(param_names)}行参数数据，实际读取到{df.shape[0]}行")
    
    data_dict = {}
    for param_idx, param_name in enumerate(param_names):
        values = df.iloc[param_idx, :].values.astype(float)
        if len(values) != 24:  # 检查列数
            raise ValueError(f"参数'{param_name}'行应包含24个数据，实际为{len(values)}个")
        data_dict[param_name] = values
    
    return data_dict


def read_scenario_data(file_path):
    df = pd.read_excel(file_path, header=None)  # header=None 表示没有表头

    # 将 DataFrame 转换为二维列表
    data = df.values.tolist()

    return data


def read_reservoir_data(file_path):
    # 参数名称定义（对应文件行顺序）
    param_names = [
        "水力发电系数", "电力抽水系数","水头差", 
        "出力上限", "出力下限", "爬坡系数", 
        "初始水位", "水位上限", "水位下限",
        "发电成本系数","储能成本系数","日流量"
    ]
    
    # 读取并验证数据
    df = pd.read_excel(file_path, header=None)
    
    if df.shape[0] != len(param_names):
        raise ValueError(f"需要{len(param_names)}行参数数据，实际读取到{df.shape[0]}行")
    
    # 构建参数名到数据的字典（不再转置）
    data_dict = {}
    for param_idx, param_name in enumerate(param_names):
        values = df.iloc[param_idx, :].values.astype(float)
        if len(values) != 7:  # 检查列数
            raise ValueError(f"参数'{param_name}'行应包含7个数据，实际为{len(values)}个")
        data_dict[param_name] = values
    
    return data_dict  # 返回字典，键为参数名，值为7水库的数据列表

def power_constraint(X):
    """
    计算水电站出力值，并确保其在出力上下限范围内
    
    参数:
        reservoir (dict): 包含水库参数的字典，需包含以下键：
            - '水力发电系数': 水力发电效率系数
            - '出库流量': 水库出库流量 (m³/s)
            - '水头差': 水头差 (m)
            - '出力上限': 最大允许出力 (MW)
            - '出力下限': 最小允许出力 (MW)
    
    返回:
        float: 满足约束的出力值 (MW)
    """
    # 提取参数
    reservoir = read_reservoir_data("./random_reservoir_matrix.xlsx")
    hydro_coeff = reservoir['水力发电系数']  # 水力发电系数
    head_diff = reservoir['水头差']          # 水头差 (m)
    power_max = reservoir['出力上限']        # 出力上限 (MW)
    power_min = reservoir['出力下限']        # 出力下限 (MW)
    v_max = reservoir['爬坡系数']
    h_0 = reservoir['初始水位']
    h_max = reservoir['水位上限']
    h_min = reservoir['水位下限']
    # 计算各个时刻理论出力值

    # 计算每个水库的综合系数
    K = hydro_coeff*head_diff
    K = K.reshape(-1, 1)  # 转换为列向量 (7,1)

    # 计算发电功率
    P = X * K* 0.01  # 广播乘法，结果形状为(7,24)
    P_min = power_min.reshape(-1,1)
    P_max = power_max.reshape(-1,1)
    P_lower_bound = (P>=P_min) #功率上限约束
    P_upper_bound = (P<=P_max) #功率下限约束

    # 计算爬坡约束 (7,167)
    max_ramp = v_max * power_max
    max_ramp = max_ramp.reshape(-1, 1)  # (7,1)
    actual_ramp = np.abs(np.diff(P, axis=1))  # (7,167)

    # 补全第一个时间步的约束（设为True）
    first_step = np.ones((P.shape[0], 1), dtype=bool)  # (7,1)
    v_bound = np.hstack([first_step, actual_ramp <= max_ramp])  # (7,168)

    # 现在可以安全地进行逻辑与运算
    all_valid = np.all(P_lower_bound & P_upper_bound & v_bound)

    
    return all_valid
